/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

// --------------------------------------------------------------------------------
#include "StdAfx.h"
// --------------------------------------------------------------------------------
#include ".\mlist.h"
// --------------------------------------------------------------------------------
MListElement::MListElement(void)
{
	Data.Data = NULL;
	Next = NULL;
}
MListElement::~MListElement(void)
{
}
// --------------------------------------------------------------------------------
MList::MList(void)
{
	Head = NULL;
}

MList::~MList(void)
{
	CleanUp();
}

void MList::CleanUp(void)
{
MListElement* ale;

	while(Head!=NULL){
		ale = Head;
		Head = ale->Next;
		delete ale;
	}
}

//---------------------------------------------------------------------------

MListElement* MList::CreateElement(void)
{
MListElement* ale;

	try{
		ale = new MListElement;
	}
	catch(...){
		ale = NULL;
	}
	return ale;
}

//---------------------------------------------------------------------------
bool MList::AddFirst(void* data)
{
MListElement* ale;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.Data = data;
	ale->Next = Head;
	Head = ale;

	return true;
}
bool MList::AddFirstBYTE(BYTE data)
{
MListElement* ale;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.bData = data;
	ale->Next = Head;
	Head = ale;

	return true;
}
bool MList::AddFirstWORD(WORD data)
{
MListElement* ale;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.wData = data;
	ale->Next = Head;
	Head = ale;

	return true;
}
bool MList::AddFirstDWORD(DWORD data)
{
MListElement* ale;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.dData = data;
	ale->Next = Head;
	Head = ale;

	return true;
}

//---------------------------------------------------------------------------

bool MList::AddLast(void* data)
{
MListElement* ale;
MListElement* aaa;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.Data = data;
	ale->Next = NULL;


	if(Head==NULL){
		Head = ale;
		return true;
	}

	aaa = Head;
	while(aaa->Next!=NULL)
		aaa = aaa->Next;
	aaa->Next = ale;

	return true;
}
bool MList::AddLastBYTE(BYTE data)
{
MListElement* ale;
MListElement* aaa;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.bData = data;
	ale->Next = NULL;


	if(Head==NULL){
		Head = ale;
		return true;
	}

	aaa = Head;
	while(aaa->Next!=NULL)
		aaa = aaa->Next;
	aaa->Next = ale;

	return true;
}
bool MList::AddLastWORD(WORD data)
{
MListElement* ale;
MListElement* aaa;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.wData = data;
	ale->Next = NULL;


	if(Head==NULL){
		Head = ale;
		return true;
	}

	aaa = Head;
	while(aaa->Next!=NULL)
		aaa = aaa->Next;
	aaa->Next = ale;

	return true;
}
bool MList::AddLastDWORD(DWORD data)
{
MListElement* ale;
MListElement* aaa;

	ale = CreateElement();
	if(ale==NULL) return false;

	ale->Data.dData = data;
	ale->Next = NULL;


	if(Head==NULL){
		Head = ale;
		return true;
	}

	aaa = Head;
	while(aaa->Next!=NULL)
		aaa = aaa->Next;
	aaa->Next = ale;

	return true;
}

//---------------------------------------------------------------------------

bool MList::Delete(int idx)
{
MListElement* ale;
MListElement* ple;
int i;

	if(Head==NULL) return false;
	if(idx<0) return false;
	if(idx>=GetCount()) return false;

	ple = NULL;
	ale = Head;
	i = 0;
	while(i<idx){
		ple = ale;
		if(ale==NULL) return false;
		ale = ale->Next;
		i++;
	}

	if(ale==NULL) return false;

	if(ple==NULL){
		Head = ale->Next;
		delete ale;
	}
	else{
		ple->Next = ale->Next;
		delete ale;
	}

	return true;
}

//---------------------------------------------------------------------------

int MList::GetCount(void)
{
MListElement* ale;
int i;

	if(Head == NULL) return 0;

	i = 0;
	ale = Head;
	while(ale!=NULL){
		i++;
		ale = ale->Next;
	}

	return i;
}

//---------------------------------------------------------------------------

MListElement* MList::GetALE(int idx)
{
MListElement* ale;
int i;

	if(Head==NULL) return NULL;
	if(idx<0) return NULL;
	if(idx>=GetCount()) return NULL;

	i = 0;
	ale = Head;
	while(i<idx){
		if(ale!=NULL)
			ale = ale->Next;
		i++;
	}
	return ale;
}

//---------------------------------------------------------------------------

void* MList::GetItem(int idx)
{
MListElement* ale;

	ale = GetALE(idx);
	if(ale==NULL) return NULL;

	return ale->Data.Data;
}
BYTE MList::GetItemBYTE(int idx)
{
MListElement* ale;

	ale = GetALE(idx);
	if(ale==NULL) return 0;

	return ale->Data.bData;
}
WORD MList::GetItemWORD(int idx)
{
MListElement* ale;

	ale = GetALE(idx);
	if(ale==NULL) return 0;

	return ale->Data.wData;
}
DWORD MList::GetItemDWORD(int idx)
{
MListElement* ale;

	ale = GetALE(idx);
	if(ale==NULL) return 0;

	return ale->Data.dData;
}

//---------------------------------------------------------------------------

bool MList::SetItem(int idx, void* data)
{
MListElement* ale;

	ale = GetALE(idx);
	if(ale==NULL) return false;
	
	ale->Data.Data = data;
	return true;
}

//---------------------------------------------------------------------------

MListElement* MList::GetHead(void)
{
	return Head;
}

//---------------------------------------------------------------------------

void MList::Clear(void)
{
	CleanUp();
}

// --------------------------------------------------------------------------------
